package team.first.movieapiv1pro.util;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.text.ParseException;
import java.util.Date;
import java.util.Objects;

/**
 * @Author: HAPPY
 * @Project_name: project
 * @Package_name: team.first.movieapiv1pro
 * @Date: 2021/12/24 16:43
 * @Description:
 */
@Setter
@Getter
@Accessors(chain = true)
public class JWTHS256 {
    /**
     * 创建秘钥
     */
    private static final byte[] SECRET = "6MNSobBRCHGIO0fS6MNSobBRCHGIO0fS".getBytes();

    /**
     * 默认过期时间30分钟
     */
    public static long EXPIRE_TIME = 1000 * 60 * 30;

    /**
     * 生成Token
     *
     * @param key
     * @return
     */
    public static String buildJWT(String key) {

        try {
            /**
             * 1.创建一个32-byte的密匙
             */
            MACSigner macSigner = new MACSigner(SECRET);

            /**
             * 2. 建立payload 载体
             * iss: 该JWT的签发者
             * sub: 该JWT所面向的用户
             * aud: 接收该JWT的一方
             * exp(expires): 什么时候过期，这里是一个Unix时间戳
             * iat(issued at): 在什么时候签发的
             */
            JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                    .issuer("HAPPY")
                    .subject("user")
                    .audience(key)
                    .expirationTime(new Date(System.currentTimeMillis() + EXPIRE_TIME)) // 设置过期时间为当前是系统时间 + 一个自定义的时长
                    .claim("email", key) // 自定义信息
                    .build();

            /**
             * 3. 建立签名
             */
            SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
            signedJWT.sign(macSigner);

            /**
             * 4. 生成token
             */
            return signedJWT.serialize();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 校验token
     *
     * @param token
     * @return
     */
    public static String validToken(String token) {
        try {
            SignedJWT jwt = SignedJWT.parse(token);
            JWSVerifier verifier = new MACVerifier(SECRET);
            //校验是否有效
            if (!jwt.verify(verifier)) {
                return "Token 无效";
            }

            //校验超时
            Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime();
            if (new Date().after(expirationTime)) {
                return "Token 已过期";
            }

            //获取载体中的数据
            Object tokenKey = jwt.getJWTClaimsSet().getClaim("email");
            //是否有openUid
            if (Objects.isNull(tokenKey)) {
                return "账号为空";
            }
            return tokenKey.toString();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取token头部信息
     * @param token token字符串
     * @return 返回的头部
     */
    public static String getHeader(String token) {
        try {
            SignedJWT jwt = SignedJWT.parse(token);

            Payload payload = jwt.getPayload();
            System.out.println(payload);
            return jwt.getHeader().toString();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getTokenExpireTime(String token) {
        SignedJWT jwt = null;
        try {
            jwt = SignedJWT.parse(token);
            return jwt.getJWTClaimsSet().getExpirationTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}
